package com.strongbj.iot.devices.reader.request.handle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.iot.devices.reader.message.ReaderMessageFactory;
import com.strongbj.iot.devices.reader.request.entity.CallLabel;
import com.strongbj.iot.devices.reader.request.message.MQMessage;
import com.strongbj.iot.devices.reader.server.ReaderServer;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelMatcher;
/**
 * 点亮标签的处理
 * @author yuzhantao
 *
 */
public class DataCenterCallLabelHandle implements IMessageHandle<MQMessage<Object>,Object>{
	private static Logger logger = LogManager.getLogger(DataCenterCallLabelHandle.class.getName());
	private final static String ACTION_CODE = "collect010";
	private ReaderMessageFactory rmFactory=new ReaderMessageFactory();
	
	@Override
	public boolean isHandle(MQMessage<Object> t) {
		if(t.getActionCode().equals(ACTION_CODE)){
			return true;
		}else{
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, MQMessage<Object> t) {
		logger.debug("收到点亮消息:"+JSON.toJSONString(t));
		JSONArray obj = (JSONArray) t.getAwsPostData();
		ByteBuf bs;
		try {
			Map<String,List<CallLabel>> map = new HashMap<>();
			// 将同一个Reader设备的标签归类
			for(CallLabel lab : obj.toJavaList(CallLabel.class)){
				String key = lab.getDevAddrCode().toUpperCase();
				if(!map.containsKey(key)){
					map.put(key,new ArrayList<CallLabel>());
				}
				map.get(key).add(lab);
			}
			for(Map.Entry<String,List<CallLabel>> item : map.entrySet()){
				bs = Unpooled.copiedBuffer(this.messageDatasToBytes(item.getValue()));
				String hexCommand = ByteUtil.byteArrToHexString(bs.array());
				ReaderServer.channels.writeAndFlush(bs, new MyChannelMatchers());
				logger.debug("将点亮消息转换为Reader协议并发送给Reader:"+hexCommand);
				Thread.sleep(500);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * mq消息转byte数组
	 */
	private byte[] messageDatasToBytes(List<CallLabel> labs) throws Exception{
		final int LABEL_DATA_SIZE = 5;  // 一个点亮标签所占的数据大小
		byte[] data =new byte[LABEL_DATA_SIZE*labs.size()];
		
		// 将2.4g标签从“0.0.0.0”格式转为byte数组(如传过来的标签格式错误，将抛出异常)
		for(int i=0;i<labs.size();i++){
			CallLabel cl = labs.get(i);
			String[] temp = cl.getLabel24g().split("\\.");
			for(int j=0;j<temp.length;j++){
				data[i*LABEL_DATA_SIZE+j]=Integer.valueOf(temp[j]).byteValue();
			}
		
			// 第5位设置是否点亮
			data[i*5+4]=cl.getIsLight()==1?Integer.valueOf("F1", 16).byteValue():Integer.valueOf("F0", 16).byteValue();		// 31为二进制00011111；15为00001111
		}

		logger.info("点亮标签的编码："+ByteUtil.byteArrToHexString(data));
		
	    return rmFactory.createReaderMessage(
				labs.get(0).getDevAddrCode(), 
				(byte)10, 
				data);
	}
	// mq消息转byte数组
//	private byte[] messageDataToBytes(CallLabel cl) throws Exception{
//		byte[] data =new byte[5];
//		// 将2.4g标签从“0.0.0.0”格式转为byte数组(如传过来的标签格式错误，将抛出异常)
//		String[] temp = cl.getLabel24g().split("\\.");
//		for(int i=0;i<temp.length;i++){
//			data[i]=Integer.valueOf(temp[i]).byteValue();
//		}
//		
//		// 第5位设置是否点亮
//	    data[4]=cl.getIsLight()==1?Integer.valueOf("F1", 16).byteValue():Integer.valueOf("F0", 16).byteValue();		// 31为二进制00011111；15为00001111
//	    
//
//		logger.info("点亮标签的编码："+ByteUtil.byteArrToHexString(data));
//		
//	    return rmFactory.createReaderMessage(
//				cl.getDevAddrCode(), 
//				(byte)10, 
//				data);
//	}
	
	class MyChannelMatchers implements ChannelMatcher{
//		private CallLabel callLabel;
		public MyChannelMatchers()
		{
			
		}
//		public MyChannelMatchers(CallLabel callLabel){
//			this.callLabel = callLabel;
//		}
		
		@Override
		public boolean matches(Channel channel) {
//			InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
//			if(insocket.getAddress().getHostAddress().equals(this.callLabel.getDevIp())){
//				return true;
//			}else{
//				return false;
//			}
			return true;
		}
	}
}
